package com.mentaleye.controller;

import com.alibaba.fastjson.JSONObject;
import com.mentaleye.bean.AssessmentAnswerBean;
import com.mentaleye.bean.AutoFormBean;
import com.mentaleye.bean.AutoFormDataResourceBean;
import com.mentaleye.bean.UserLoginBean;
import com.mentaleye.biz.AutoFormBiz;
import com.mentaleye.biz.CommonBizImpl;
import com.mentaleye.biz.DictionaryBiz;
import com.mentaleye.biz.RoleBiz;
import com.mentaleye.biz.impl.AutoFormTemplateParseUtil;
import com.mentaleye.biz.impl.JSONHelper;
import com.mentaleye.biz.impl.TemplateUtil;
import com.mentaleye.dal.model.Assessment;
import com.mentaleye.dal.model.AssessmentAnswerWithBLOBs;
import com.mentaleye.dal.model.AutoFormDataResourceExample;
import com.mentaleye.dal.model.AutoFormDataResourceWithBLOBs;
import com.mentaleye.dal.service.AssessmentAnswerMapper;
import com.mentaleye.dal.service.AssessmentMapper;
import com.mentaleye.dal.service.AutoFormDataResourceMapper;
import com.mentaleye.enums.CommonStatus;
import com.mentaleye.enums.DictionaryEnums;
import com.mentaleye.service.AutoFormDataSourceService;
import com.mentaleye.shiro.Constants;
import com.mentaleye.shiro.RedisCache;
import com.mentaleye.shiro.RedisKeyEnum;
import com.mentaleye.util.*;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.velocity.VelocityEngineUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.velocity.VelocityConfigurer;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@Controller
@RequestMapping({"/autoForm"})
public class AutoFormController
{
  @Autowired
  private RedisCache<String, Object> redisCache;
  @Autowired
  private DictionaryBiz dictionaryBiz;
  @Autowired
  private VelocityConfigurer velocityConfigurer;
  private static Logger logger = Logger.getLogger(AutoFormController.class);

  @Autowired
  private AutoFormBiz autoFormBiz;
  @Autowired
  AutoFormDataResourceMapper autoFormDataResourceMapper;
  @Autowired
  private RoleBiz roleBiz;
  @Autowired
  private AssessmentAnswerMapper assessmentAnswerMapper;
  @Autowired
  private AssessmentMapper assessmentMapper;
  @RequestMapping({"/autoFormList"})
  public ModelAndView autoForm() {
    ModelAndView view = new ModelAndView("cm/autoForm/autoFormList");
    Map<Integer,String>   autoFormTypeMap=dictionaryBiz.queryDictionaryByParent(DictionaryEnums.FORM_TYPE.getCode());
    view.addObject("autoFormTypeMap", autoFormTypeMap);
    view.addObject("statusMap", JSONObject.toJSONString(CommonStatus.enumMap) );
    view.addObject("typeMap", JSONObject.toJSONString(autoFormTypeMap));
    return view;
  }

  @RequestMapping({"/autoFormListData"})
  @ResponseBody
  public String autoFormListData(CommonPage commonPage)
  {
    this.autoFormBiz.queryAutoFormByPage(commonPage);
    return commonPage.toSHowPage();
  }
  @RequestMapping({"/autoFormEdit"})
  public ModelAndView autoFormEdit(@RequestParam(value="id", required=false) Integer id, @RequestParam(value="version", required=false) Integer version) {
    ModelAndView view = new ModelAndView("cm/autoForm/autoFormEdit");
    Map<Integer,String> assessmentTypeMap=dictionaryBiz.queryDictionaryByParent(DictionaryEnums.FORM_TYPE.getCode());
    view.addObject("assessmentTypeMap", assessmentTypeMap);
    if (id != null) {
      view.addObject("autoForm", this.autoFormBiz.getFormById(id, version));
    }
    return view;
  }

  @RequestMapping(value={"/autoFormSelect"}, produces={"text/html;charset=UTF-8"})
  @ResponseBody
  public String autoFormSelect(@RequestParam(value="roleIds", required=false) String roleIds) {
    Map model = new HashMap();
    model.put("roles", this.roleBiz.getAllRole());
    if ((StringUtils.isNotEmpty(roleIds)) && (!"".equals(roleIds.trim()))) {
      model.put("roleSelect", roleIds.split(","));
    }
    return VelocityEngineUtils.mergeTemplateIntoString(this.velocityConfigurer.getVelocityEngine(), "cm/autoForm/autoFormSelect.vm", "UTF-8", model);
  }

  @RequestMapping({"doAdd"})
  @ResponseBody
  public CommonResult doAdd(AutoFormBean autoForm)
  {
    return new CommonResult(Boolean.valueOf(this.autoFormBiz.addForm(autoForm)));
  }

  @RequestMapping({"/autoFormReview"})
  public ModelAndView autoFormReview(@RequestParam("contents") String contents,@RequestParam("dataResourceIdsView") String dataResourceIdsView)
  {

    ModelAndView view=new ModelAndView("cm/autoForm/autoForm-review-add");
    Map<String, List<Map<String, Object>>> paras = new HashMap<String, List<Map<String, Object>>>();
    TemplateUtil.processor(contents,paras);
    String ftlContent=AutoFormTemplateParseUtil.parseHtmlForAdd( contents,paras,false,true);
    view.addObject("formContent", ftlContent);
    view.addObject("isView", true);
    return view;
  }
  @RequestMapping(value = "/delete")
  public @ResponseBody CommonResult delete(@RequestBody List<Integer> ids) {
    return  autoFormBiz.disableForm(ids);
  }

  @RequestMapping(value = "/getSelectHtml")
  public  @ResponseBody CommonResult getSelectHtml(@RequestParam(value="dataResourceIds", required=false)String dataResourceIds){

      CommonResult commonResult=new CommonResult();
    StringBuffer stringBuffer=new StringBuffer("<option value='' selected='selected'>请选择数据源</option>");
    try{
        Set<String> idSets=new HashSet<String>();
        if(StringUtils.isNotEmpty(dataResourceIds)){
            String[] ids=dataResourceIds.split(",");
            if(ids!=null&&ids.length>0){
                for(String id:ids){
                    idSets.add(id);
                }
            }
        }

      Map<String, Object> paramsMap=new  HashMap<String, Object>();
      List<Object>   result=  CommonBizImpl.queryByMap("AutoFormDataResource",paramsMap);
        AutoFormDataResourceBean autoFormDataResource;
      if(result!=null&&result.size()>0){
        for(Object data:result){
          autoFormDataResource=(AutoFormDataResourceBean)data;
          stringBuffer.append("<option value='").append(autoFormDataResource.getId()).append("'");
          if(idSets.size()>0 &&idSets.contains(autoFormDataResource.getId())){
            stringBuffer.append("selected='selected'");
          }
          stringBuffer.append(">").append(autoFormDataResource.getName()).append("</option>");
        }
      }
      Map<String,Object> data=new HashMap<String, Object>();
        data.put("html",stringBuffer.toString());
        data.put("dataList",result);
        commonResult.setData(data);
        commonResult.setIsSuccess(true);
    }catch (Exception e){
        logger.error("获取数据源选择器异常",e);
    }
    return commonResult;
  }


  @RequestMapping({"/viewContent"})
  public ModelAndView viewContent(@RequestParam(value="assessmentId")Integer assessmentId,@RequestParam(value="operate", required=false)String operate, @RequestParam("assessmentType") Integer assessmentType, @RequestParam("isForm") Boolean  isForm , @RequestParam(value="toUserId",required = false)   String toUserId) {
    String message = "";
    try {
         boolean update=false;
      boolean isView=false;
      if(StringUtils.isEmpty(operate)){
        operate = AutoFormTemplateParseUtil.OP_VIEW;
      }
      if(AutoFormTemplateParseUtil.OP_VIEW.equals(operate)){
        isView=true;
      }
      //获取参数
      String url;
      Map<String, List<Map<String, Object>>> paras = new HashMap<String, List<Map<String, Object>>>();
      String ftlContent;
      Assessment assessment=(Assessment)CommonBizImpl.getBeanById("Assessment","id",assessmentId,true);
      AutoFormBean autoForm= autoFormBiz.getFormById(assessment.getAutoFormId(),assessment.getAutoFormVersion());
      AssessmentAnswerBean assessmentAnswer= getAnswerByLogin(assessmentId,null,isForm,toUserId);
     if(assessmentAnswer==null||assessmentAnswer.getAssessmentStatus()==null){
         //req.setAttribute("formName", autoForm.getName());
       //req.setAttribute("param", paramMap);
       //paras = getFormData(autoForm,paramMap);
       ftlContent = autoForm.getParse();
     }else {
       ftlContent=assessmentAnswer.getParse();
       update=true;
     }
       if(!update){//通过模版拼接页面
         getAddHtml(assessment,autoForm,paras);
       }else{//通过上次保存的数据拼接页面

         paras= JSONHelper.json2MapList(assessmentAnswer.getContent());
       }

      ftlContent=AutoFormTemplateParseUtil.parseHtmlForAdd( ftlContent,paras,update,isView);

      ModelAndView view=new ModelAndView("cm/autoForm/autoForm-review-add");
      view.addObject("formContent", ftlContent);
      view.addObject("assessmentType", assessmentType);
      view.addObject("isView", isView);

      return view;
    } catch (Exception e) {
      e.printStackTrace();
      message = "表单添加失败："+e.getMessage();
    }
    return new ModelAndView("jeecg/cgform/autoform/autoForm-error").addObject("message", message);
  }


  /**
   * 智能提交表单
   *
   * @param
   * @return
   */
  @SuppressWarnings("rawtypes")
  @RequestMapping("addorupdateForm")
  @ResponseBody
  public CommonResult addorupdateForm(@RequestParam(value="assessmentId")Integer assessmentId,@RequestParam(value="isSubmit")Boolean isSubmit,  HttpServletRequest request , @RequestParam("assessmentType") Integer assessmentType) {
    CommonResult j = new CommonResult();
    String message = "表单保存成功";
    try{
      UserLoginBean loginBean = (UserLoginBean) redisCache.get(Constants.getRedisKey(RedisKeyEnum.USER_LOGIN,(String) SecurityUtils.getSubject().getPrincipal()));

      Map paramData = request.getParameterMap();
      if(paramData!=null){
        Map<String,Map<String,Object>> dataMap = mapConvert(paramData);
        AssessmentAnswerBean assessmentAnswer= getAnswerByLogin(assessmentId,loginBean,true);
        AssessmentAnswerWithBLOBs answerWithBLOBs=new AssessmentAnswerWithBLOBs();
        answerWithBLOBs.setAssessmentId(assessmentId);
        answerWithBLOBs.setUserId(Integer.parseInt(loginBean.getLoginId()));
        answerWithBLOBs.setContent(JSONHelper.map2json(dataMap));
        if(isSubmit){
          answerWithBLOBs.setAssessmentStatus(CommonStatus.READY.getCode());
        }else{
          answerWithBLOBs.setAssessmentStatus(CommonStatus.WAIT.getCode());
        }

        if(assessmentAnswer==null||assessmentAnswer.getAssessmentStatus()==null){
          Assessment   assessment=(Assessment)CommonBizImpl.getBeanById("Assessment","id",assessmentId,true);
          AutoFormBean autoForm= autoFormBiz.getFormById(assessment.getAutoFormId(),assessment.getAutoFormVersion());
          answerWithBLOBs.setParse(autoForm.getParse());

          assessmentAnswerMapper.insertSelective(answerWithBLOBs);

        }else{
          assessmentAnswerMapper.updateByPrimaryKeySelective(answerWithBLOBs);

        }
        if(DictionaryEnums.FORM_TYPE_ASSESSMENT.getCode().intValue()==assessmentType.intValue()){
          Assessment record=new Assessment();
          record.setId(assessmentId);
          record.setAssessmentStatus(CommonStatus.READY.getCode());
          assessmentMapper.updateByPrimaryKeySelective(record);
        }
      }
    }catch(Exception e){
      logger.error("填写异常",e);
      j.setIsSuccess(false);
      message = "表单保存失败";
    }
    j.setResultMsg(message);
    return j;
  }



  public static Map<String,Map<String,Object>> mapConvert(Map map) {
    Map<String,Map<String,Object>> dataMap = new HashMap<String, Map<String,Object>>();
    Map<String,Object> subDataMap= null;
    if(map!=null){
      Iterator it=map.entrySet().iterator();
      while(it.hasNext()){
        Map.Entry entry=(Map.Entry)it.next();
        Object ok=entry.getKey();
        Object ov=entry.getValue()==null?"":entry.getValue();
        String key=ok.toString();
        String keyval="";
        String[] value=new String[1];
        if(ov instanceof String[]){
          value=(String[])ov;
        }else{
          value[0]=ov.toString();
        }
        keyval+=value[0];
        for(int k=1;k<value.length;k++){
          keyval+=","+value[k];
        }
        String [] keys = key.split("\\.");
        if(keys.length==2){
          String index = "";
          if(keys[1].indexOf("[")!=-1){
            index = keys[1].substring(keys[1].indexOf("["));
            keys[0] = keys[0]+index;
            keys[1] = keys[1].substring(0,keys[1].indexOf("["));
          }
          subDataMap = dataMap.get(keys[0]);
          if(subDataMap!=null){
            subDataMap.put(keys[1], keyval);
          }else{
            subDataMap= new HashMap<String, Object>();
            subDataMap.put(keys[1], keyval);
            dataMap.put(keys[0], subDataMap);
          }
          logger.info("ds:"+keys[0]+";name:"+keys[1]+";value:"+keyval);
        }else{
          String paramKey = "param";
          subDataMap = dataMap.get(paramKey);
          if(subDataMap!=null){
            subDataMap.put(keys[0], keyval);
          }else{
            subDataMap= new HashMap<String, Object>();
            subDataMap.put(keys[0], keyval);
            dataMap.put(paramKey, subDataMap);
          }
          logger.info("ds:"+paramKey+";name:"+keys[0]+";value:"+keyval);
        }

      }
    }
    return dataMap;
  }


  private  void getAddHtml(     Assessment assessment ,  AutoFormBean autoForm,  Map<String, List<Map<String, Object>>> paras){
    String dataSourcesId=autoForm.getDataResourceIds();
    if(StringUtils.isNotEmpty(dataSourcesId)){
      String[] dataSourceList=dataSourcesId.split(",");
      if(dataSourceList!=null&&dataSourceList.length>0){
        List<Integer> idList=new ArrayList<Integer>();
        for(String id:dataSourceList){
          if(StringUtils.isNotEmpty(id)){
            idList.add(Integer.parseInt(id));
          }
        }
        AutoFormDataResourceExample autoFormDataResourceExample=new AutoFormDataResourceExample();
        autoFormDataResourceExample.createCriteria().andIdIn(idList);
        List<AutoFormDataResourceWithBLOBs> autoFormDataResources=  autoFormDataResourceMapper.selectByExampleWithBLOBs(autoFormDataResourceExample);
        if(autoFormDataResources!=null&&autoFormDataResources.size()>0){
          String sql;
          String sqlCondition=assessment.getAutoFormDataField();
          Map<String ,Object> conditionMap=null;
          List<Map<String, Object>> sqlDataMap;
          if(StringUtils.isNotEmpty(sqlCondition)){
            conditionMap= JSONHelper.json2Map(sqlCondition);
          }
          for(AutoFormDataResourceWithBLOBs autoFormDataResource:autoFormDataResources){
            sql=autoFormDataResource.getDbDynSql();
            if(StringUtils.isNotEmpty(sql)&&conditionMap!=null){
              for(Map.Entry<String,Object> entry:conditionMap.entrySet()){
                sql=  sql.replace("#{"+entry.getKey()+"}",(String)entry.getValue());
              }
              sqlDataMap= getTableBySql(sql);
              if(sqlDataMap!=null){
                paras.put(String.valueOf(autoFormDataResource.getId()),sqlDataMap);
              }
            }
          }
        }
      }
    }
  }

   //根据数据源 返回数据
  private  List<Map<String, Object>>  getTableBySql(String dataSql){
    AutoFormDataSourceService autoFormDataSourceService= (AutoFormDataSourceService) ContextUtil.getBean(AutoFormDataSourceService.class);
   return autoFormDataSourceService.explanSql(MultipleTansferUtil.getMybatisSql(dataSql));

  }

  private  AssessmentAnswerBean getAnswerByLogin(Integer assessmentId,UserLoginBean loginBean,Boolean isForm){
    return getAnswerByLogin(  assessmentId,  loginBean,  isForm,null);

  }

  private AssessmentAnswerBean getAnswerByLogin(Integer assessmentId, UserLoginBean loginBean, Boolean isForm, String toUserId){
    if(loginBean==null
            ){
      loginBean = (UserLoginBean) redisCache.get(Constants.getRedisKey(RedisKeyEnum.USER_LOGIN,(String) SecurityUtils.getSubject().getPrincipal()));

    }
    Map<String, Object> paramMap=new HashMap<String, Object>();
    paramMap.put("assessmentId",assessmentId);
    if(isForm){
      paramMap.put("fromNo",loginBean.getLoginId());
      if(StringUtils.isNotEmpty(toUserId)){
        paramMap.put("toNo",toUserId);
      }
    }else {
      paramMap.put("toNo",loginBean.getLoginId());
    }
    List<AssessmentAnswerBean> autoFormBeen= ObjectUtil.transferListMap(assessmentAnswerMapper.selectByMap(paramMap), AssessmentAnswerBean.class);

    return autoFormBeen.get(0);

  }
}